﻿#include"XQMail.h"
#include<QTcpSocket>
#include<QHostInfo>
#include<QDateTime>
#include<QFileInfo>
#include<QDebug>
QByteArray XQMail::prepareDate()
{
	QDateTime currentDateTime = QDateTime::currentDateTime();
	QString formattedDateTime = currentDateTime.toString("ddd, dd MMM yy hh:mm:ss +0800");
	return formattedDateTime.toLocal8Bit();
}
int XQMail::sendRequest(const QByteArray& content, bool bout)
{
	return m_tcp->write(content);
}
bool XQMail::rcvResponse(const QByteArray& expected_response)
{
	if (m_tcp->waitForReadyRead())
	{
		auto response =m_tcp->readAll();
		if (response.mid(0, 3) != expected_response)
		{
			return false;
		}
		return true;
	}
	return true;
}
bool XQMail::CReateSocket()
{
	//qInfo() << "开始建立tcp连接";
	if (m_tcp == nullptr)
	{
		m_tcp = new QTcpSocket(this);
		//connect(m_tcp, &QTcpSocket::errorOccurred, [this] {m_tcp->errorString(); });
		connect(m_tcp, &QTcpSocket::connected, this, &XQMail::connected);
		connect(m_tcp, &QTcpSocket::disconnected, this, &XQMail::disconnected);
	}
	//qInfo() << m_ServerName << m_Port;
	//连接服务器
	m_tcp->connectToHost(m_ServerName,m_Port);
	//完成连接
	if (m_tcp->waitForConnected()&& rcvResponse("220")) // 等待连接建立
		return true;
	return false;
}

bool XQMail::Logon()
{
	QString localHostName = QHostInfo::localHostName();

	QByteArray msg;

	msg = "HELO ";
	msg += localHostName.toLocal8Bit() + "\r\n";
	sendRequest(msg);
	if (!rcvResponse("250"))
	{
		return false;
	}

	msg = "AUTH LOGIN\r\n";
	sendRequest(msg);
	if (!rcvResponse("334"))
	{
		return false;
	}


	msg = m_UserName.toLocal8Bit().toBase64() + "\r\n";
	sendRequest(msg);
	if (!rcvResponse("334"))
	{
		return false;
	}

	msg = m_UserPwd.toLocal8Bit().toBase64() + "\r\n";
	sendRequest(msg);
	if (!rcvResponse("235"))
	{
		return false;
	}

	return true;//登录成功  
}

bool XQMail::SendHead()
{
	QByteArray msg;

	msg = "MAIL FROM:<";
	msg += m_SenderAddr.toLocal8Bit() + ">\r\n";
	sendRequest(msg);
	if (!rcvResponse("250"))
	{
		//m_logInfo.logInfo("邮件地址错误：%s", m_SenderAddr.c_str());
		return false;
	}

	//遍历获得接收者的邮箱
	for (auto &rec:m_Receivers)
	{
		msg = "RCPT TO: <";
		msg += rec.toLocal8Bit() + ">\r\n";
		sendRequest(msg);
		if (!rcvResponse("250"))
		{
			return false;
		}
	}

	msg = "DATA\r\n";
	sendRequest(msg);
	if (!rcvResponse("354"))
	{
		return false;
	}

	//发送Headers
	msg = "From:\"" + m_SenderName.toLocal8Bit() + "\"<" + m_SenderAddr.toLocal8Bit() + ">\r\n";

	//遍历receiver
	msg += "To: ";
	for (auto itrRec = m_Receivers.begin(); itrRec != m_Receivers.end(); itrRec++)
	{
		QByteArray szRecv;
		szRecv = "\"" + itrRec.key().toLocal8Bit() + "\"<" + itrRec.value().toLocal8Bit() + ">, ";
		msg += szRecv;
	}
	msg += "\r\n";

	msg += "Date: ";
	msg += prepareDate() + "\r\n";

	msg += "Subject: ";
	msg += m_MailTitle.toLocal8Bit() + "\r\n";

	msg += "X-Mailer: six_beauty \r\n";

	msg += "MIME-Version: 1.0\r\n";
	msg += "Content-type: multipart/mixed;  boundary=\"INVT\"\r\n\r\n";

	msg += "\r\n";
	sendRequest(msg);

	return true;
}

bool XQMail::SendTextBody()
{
	QByteArray msg;
	msg = "--INVT\r\nContent-Type: text/plain;\r\n  charset=\"gb2312\"\r\n\r\n";
	msg += m_TextBody.toLocal8Bit();
	msg += "\r\n\r\n";
	int len_s = sendRequest(msg, true);

	if (len_s != msg.length())
	{
		//m_logInfo.logInfo("发送邮件正文出错，应该发送长度（%d）：实际发送长度（%d）", msg.length(), len_s);
		return false;
	}

	return true;
}

bool XQMail::SendFileBody()
{
	QByteArray msg;
	//遍历发送附件文件
	for (auto itrList = m_FilePathList.begin(); itrList != m_FilePathList.end(); itrList++)
	{
		QByteArray filePath = itrList->toLocal8Bit();
		QByteArray fileName = QFileInfo(*itrList).fileName().toLocal8Bit();
		QByteArray szContent = QFile(*itrList).readAll();

		msg = "--INVT\r\nContent-Type: application/octet-stream;\r\n  name=\"";
		msg += fileName;
		msg += "\"\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment;\r\n  filename=\"";
		msg += fileName;
		msg += "\"\r\n\r\n";
		sendRequest(msg, true);

		int npos = 0, len = szContent.length();
		while (npos < len)
		{
			QByteArray szBuffer = szContent.mid(npos, qMin(len - npos, 3000)).toBase64();
			szBuffer += "\r\n";
			sendRequest(szBuffer);
			npos += qMin(len - npos, 3000);
		}
	}

	return true;
}

bool XQMail::SendEnd()
{
	QByteArray msg;

	msg = "--INVT--\r\n.\r\n";
	sendRequest(msg, true);

	msg = "QUIT\r\n";
	sendRequest(msg, true);
	m_tcp->close();
	return true;
}
